package com.example.myapplication;

import android.app.AlertDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.provider.Settings;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.tencent.rtmp.TXLiveConstants;
import com.tencent.rtmp.TXLivePusher;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.Hashtable;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class TXLivePushActivity extends AppCompatActivity implements View.OnClickListener, ServiceConnection {

    private OkHttpClient mOkHttpClient;
    private String rtmpPushUrl;
    private String rtmpPlayUrl;
    private Bitmap bitmap;
    private ImageView iv_code;
    private FloatingVideoService.MyBinder myBinder;
    private TXLivePusher mLivePusher;
    private boolean isPushing;
    private boolean isCameraOpen;
    private ImageView iv_push;
    private ImageView camera_switch;
    private Intent intent;
    private AlertDialog.Builder builder;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        WindowManager.LayoutParams localLayoutParams = getWindow().getAttributes();
        localLayoutParams.flags = (WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | localLayoutParams.flags);
        setContentView(R.layout.activity_t_x_live_push);
        intiView();
        intoUrl();
    }

    /**
     * 获取测试推拉流地址
     */
    private void intoUrl() {
        if (mOkHttpClient == null) {
            mOkHttpClient = new OkHttpClient().newBuilder()
                    .connectTimeout(10, TimeUnit.SECONDS)
                    .readTimeout(10, TimeUnit.SECONDS)
                    .writeTimeout(10, TimeUnit.SECONDS)
                    .build();
        }
        String reqUrl = "https://lvb.qcloud.com/weapp/utils/get_test_pushurl";
        Request request = new Request.Builder()
                .url(reqUrl)
                .addHeader("Content-Type", "application/json; charset=utf-8")
                .build();
        Log.d("lin", "start fetch push url");
        mOkHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(TXLivePushActivity.this, "获取推流地址失败", Toast.LENGTH_SHORT).show();
                    }
                });
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.isSuccessful()) {
                    JSONObject jsonRsp;
                    try {
                        jsonRsp = new JSONObject(response.body().string());
                        rtmpPushUrl = jsonRsp.optString("url_push");            // RTMP 推流地址
                        rtmpPlayUrl = jsonRsp.optString("url_play_rtmp");   // RTMP 播放地址
                        bitmap = createQRCodeBitmap(rtmpPlayUrl, 800, 800, "UTF-8", "H", "1", Color.BLACK, Color.WHITE);
                        if (bitmap != null) {
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    iv_code.setImageBitmap(bitmap);
                                }
                            });
                        }
                        Log.e("lin", "------- rtmpPushUrl=" + rtmpPushUrl);
                        Log.e("lin", "------- rtmpPlayUrl=" + rtmpPlayUrl);
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
    }

    /**
     * 初始化view
     */
    private void intiView() {
        iv_code = findViewById(R.id.iv_code);


        iv_push = findViewById(R.id.iv_push);
        camera_switch = findViewById(R.id.camera_switch);
        ImageView iv_qrcode = findViewById(R.id.iv_qrcode);
        ImageView iv_close = findViewById(R.id.iv_close);
        iv_push.setOnClickListener(this);
        camera_switch.setOnClickListener(this);
        iv_qrcode.setOnClickListener(this);
        iv_close.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.iv_push:
                if (isPushing) {
                    stopPush();
                } else {
                    startPush();
                }
                isPushing = mLivePusher.isPushing();
                break;
            case R.id.camera_switch:
                if (isCameraOpen) {
                    myBinder.close();
                    camera_switch.setImageResource(R.mipmap.camera_on);
                    isCameraOpen = false;
                } else {
                    if (intent == null) {
                        startFloating();
                    } else {
                        open(true);
                    }
                }
                break;
            case R.id.iv_qrcode:
                statusQRCode();
                break;
            case R.id.iv_close:
                showExitInfoDialog("当前正在直播，是否退出直播？",false);
                break;
            default:
        }
    }

    private Handler handler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            if (msg.what == 1) {
                number = 1;
            } else {
                myBinder.start();
                camera_switch.setImageResource(R.mipmap.camera_off);
            }
            return false;
        }
    });

    private int number = 1;

    @Override
    public void onBackPressed() {
        if (number == 1) {
            Toast.makeText(this, "再按一次退出", Toast.LENGTH_SHORT).show();
            number++;
            handler.sendEmptyMessageDelayed(1, 2000);
        } else {
            finish();
        }
    }

    /**
     * 显示确认消息
     *
     * @param msg     消息内容
     * @param isError true错误消息（必须退出） false提示消息（可选择是否退出）
     */
    public void showExitInfoDialog(String msg, Boolean isError) {
        if (builder == null) {
            builder = new AlertDialog.Builder(this);
            builder.setCancelable(true);
        }
        builder.setTitle(msg);

        if (!isError) {
            builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                    finish();
                }
            });
            builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                }
            });
        } else {
            //当情况为错误的时候，直接停止推流
//            release();
            builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                }
            });
        }
        AlertDialog alertDialog = builder.create();
        alertDialog.show();
        alertDialog.setCanceledOnTouchOutside(false);
    }

    public void statusQRCode() {
        if (iv_code.getVisibility() == View.VISIBLE) {
            iv_code.setVisibility(View.GONE);
        } else {
            iv_code.setVisibility(View.VISIBLE);
        }
    }

    /**
     * 初始化悬浮窗
     */
    public void startFloating() {
        if (!Settings.canDrawOverlays(this)) {
            Toast.makeText(this, "当前无权限，请授权", Toast.LENGTH_SHORT);
            startActivityForResult(new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName())), 2);
        } else {
            intent = new Intent(this, FloatingVideoService.class);
            bindService(intent, this, Context.BIND_AUTO_CREATE);
            open(false);
        }
    }

    /**
     * 打卡摄像头预览
     *
     * @param b false 第一次打开，不需要添加view  true 后续打开，每次要添加view
     */
    public void open(boolean b) {
        if (b) {
            myBinder.addView();
        }
        handler.sendEmptyMessageDelayed(2, 50);
        isCameraOpen = true;
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == 2) {
            if (!Settings.canDrawOverlays(this)) {
                Toast.makeText(this, "授权失败", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(this, "授权成功", Toast.LENGTH_SHORT).show();
                startFloating();
            }
        }
    }

    /**
     * 开启录屏推流
     */
    private void startPush() {
        if (mLivePusher == null) {
            mLivePusher = new TXLivePusher(this);
        }
        mLivePusher.setVideoQuality(TXLiveConstants.VIDEO_QUALITY_SUPER_DEFINITION, false, false);//设置编码格式
        int ret = mLivePusher.startPusher(rtmpPushUrl);
        mLivePusher.startScreenCapture();//录屏
        if (ret == -5) {
            Toast.makeText(this, "startRTMPPush: license 校验失败", Toast.LENGTH_SHORT).show();
            Log.e("lin", "startRTMPPush: license 校验失败");
        } else if (ret == -1) {
            Toast.makeText(this, "startRTMPPush: 启动推流失败", Toast.LENGTH_SHORT).show();
            Log.e("lin", "startRTMPPush: 启动推流失败");
        } else if (ret == 0) {
            iv_push.setImageResource(R.mipmap.livepusher_pause);
            Toast.makeText(this, "sstartRTMPPush: 启动推流成功", Toast.LENGTH_SHORT).show();
            Log.e("lin", "startRTMPPush: 启动推流成功");
        }
    }

    /**
     * 停止录屏推流
     */
    private void stopPush() {
        mLivePusher.stopScreenCapture();
        mLivePusher.stopPusher();
        iv_push.setImageResource(R.mipmap.livepusher_start);
        Toast.makeText(this, "sstartRTMPPush: 已停止录屏", Toast.LENGTH_SHORT).show();
    }

    public Bitmap createQRCodeBitmap(String content, int width, int height,
                                     String character_set, String error_correction_level,
                                     String margin, int color_black, int color_white) {
        if (TextUtils.isEmpty(content)) {
            return null;
        }
        if (width < 0 || height < 0) {
            return null;
        }
        try {
            Hashtable<EncodeHintType, String> hints = new Hashtable<>();
            if (!TextUtils.isEmpty(character_set)) {
                hints.put(EncodeHintType.CHARACTER_SET, character_set);
            }
            if (!TextUtils.isEmpty(error_correction_level)) {
                hints.put(EncodeHintType.ERROR_CORRECTION, error_correction_level);
            }
            if (!TextUtils.isEmpty(margin)) {
                hints.put(EncodeHintType.MARGIN, margin);
            }
            BitMatrix bitMatrix = new QRCodeWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);

            int[] pixels = new int[width * height];
            for (int y = 0; y < height; y++) {
                for (int x = 0; x < width; x++) {
                    if (bitMatrix.get(x, y)) {
                        pixels[y * width + x] = color_black;
                    } else {
                        pixels[y * width + x] = color_white;
                    }
                }
            }
            Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
            bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
            return bitmap;
        } catch (WriterException e) {
            e.printStackTrace();
            return null;
        }
    }


    private void release() {
        if (mLivePusher != null) {
            stopPush();
            mLivePusher = null;
        }
        if (myBinder != null&&isCameraOpen) {
            myBinder.close();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        release();
        if (intent != null) {
            unbindService(this);
        }
        if (handler != null) {
            handler.removeCallbacksAndMessages(null);
            handler = null;
        }
    }

    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        if (service instanceof FloatingVideoService.MyBinder) {
            myBinder = (FloatingVideoService.MyBinder) service;
        }
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {

    }

}